package com.ddddddl.widget.scrollTab;

import java.util.ArrayList;
import java.util.List;

import android.R;
import android.app.LocalActivityManager;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.util.AttributeSet;
import android.util.Log;
import android.view.KeyEvent;
import android.view.SoundEffectConstants;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.Window;
import android.widget.BaseAdapter;
import android.widget.LinearLayout;

public class ScrollTab extends LinearLayout implements
		ViewTreeObserver.OnTouchModeChangeListener, ViewFlow.ViewSwitchListener {

	private FlingTabWidget tabWidget;
	private ViewFlow tabContent;
	private CircleFlowIndicator indicator;
	private TabAdapter adapter;
	private List<TabSpec> tabSpecs = new ArrayList<TabSpec>(2);

	private LocalActivityManager localActivityManager;
	private OnTabChangeListener onTabChangeListener;
	private OnKeyListener tabKeyListener;

	public ScrollTab(Context context) {
		super(context);
		init();
	}

	public ScrollTab(Context context, AttributeSet attrs) {
		super(context, attrs);
		init();
	}

	private void init() {
		setFocusableInTouchMode(true);
		setDescendantFocusability(FOCUS_AFTER_DESCENDANTS);
	}

	public TabSpec newTabSpec(String tag) {
		return new TabSpec(tag);
	}

	public void setup() {
		tabWidget = (FlingTabWidget) findViewById(R.id.tabs);
		if (tabWidget == null) {
			throw new RuntimeException(
					"Your TabHost must have a TabWidget whose id attribute is 'android.R.id.tabs'");
		}

		// KeyListener to attach to all tabs. Detects non-navigation keys
		// and relays them to the tab content.
		tabKeyListener = new OnKeyListener() {
			public boolean onKey(View v, int keyCode, KeyEvent event) {
				switch (keyCode) {
				case KeyEvent.KEYCODE_DPAD_CENTER:
				case KeyEvent.KEYCODE_DPAD_LEFT:
				case KeyEvent.KEYCODE_DPAD_RIGHT:
				case KeyEvent.KEYCODE_DPAD_UP:
				case KeyEvent.KEYCODE_DPAD_DOWN:
				case KeyEvent.KEYCODE_ENTER:
					return false;

				}
				tabContent.requestFocus(View.FOCUS_FORWARD);
				return tabContent.dispatchKeyEvent(event);
			}

		};

		tabWidget
				.setTabSelectionListener(new FlingTabWidget.OnTabSelectionChanged() {
					public void onTabSelectionChanged(int tabIndex,
							boolean clicked) {
						setCurrentTab(tabIndex, true);
						if (clicked) {
							tabContent.requestFocus(View.FOCUS_FORWARD);
						}
					}
				});

		tabContent = (ViewFlow) findViewById(R.id.tabcontent);
		if (tabContent == null) {
			throw new RuntimeException(
					"Your TabHost must have a FrameLayout whose id attribute is 'android.R.id.tabcontent'");
		}
		adapter = new TabAdapter();

		indicator = (CircleFlowIndicator) findViewById(com.ddddddl.zhangben.R.id.circleflowindicator);

		tabContent.setAdapter(adapter);
		tabContent.setFlowIndicator(indicator);
		indicator.setViewFlow(tabContent);
	}

	public void setupChild() {
		tabContent.renderChild();
		tabWidget.focusCurrentTab(0);
		invokeOnTabChangeListener(false);
	}

	public void setup(LocalActivityManager activityGroup) {
		setup();
		localActivityManager = activityGroup;
	}

	@Override
	protected void onAttachedToWindow() {
		super.onAttachedToWindow();
		final ViewTreeObserver treeObserver = getViewTreeObserver();
		if (treeObserver != null) {
			treeObserver.addOnTouchModeChangeListener(this);
		}
		tabContent.setOnViewSwitchListener(this);
	}

	@Override
	protected void onDetachedFromWindow() {
		super.onDetachedFromWindow();
		final ViewTreeObserver treeObserver = getViewTreeObserver();
		if (treeObserver != null) {
			treeObserver.removeOnTouchModeChangeListener(this);
		}
	}

	public void setCuteValue(int value) {
		if (indicator != null)
			indicator.setCuteValue(value);
	}

	public void setCuteValue() {
		if (indicator != null)
			indicator.setCuteValue();
	}

	/**
	 * {@inheritDoc}
	 */
	public void onTouchModeChanged(boolean isInTouchMode) {
		if (!isInTouchMode) {

			if (!tabContent.getSelectedView().hasFocus()
					|| tabContent.getSelectedView().isFocused()) {
				tabWidget.getChildTabViewAt(
						tabContent.getSelectedItemPosition()).requestFocus();
			}
		}
	}

	public void addTab(TabSpec tabSpec) {

		if (tabSpec.indicatorStrategy == null) {
			throw new IllegalArgumentException(
					"you must specify a way to create the tab indicator.");
		}

		if (tabSpec.contentStrategy == null) {
			throw new IllegalArgumentException(
					"you must specify a way to create the tab content");
		}
		View tabIndicator = tabSpec.indicatorStrategy.createIndicatorView();
		tabIndicator.setOnKeyListener(tabKeyListener);

		LayoutParams params = (LayoutParams) tabIndicator.getLayoutParams();
		params.weight = 1.0f;
		tabIndicator.setLayoutParams(params);
		tabWidget.addView(tabIndicator);
		tabSpecs.add(tabSpec);
	}

	public void clearAllTabs() {
		tabWidget.removeAllViews();
		init();
		tabContent.removeAllViews();
		tabSpecs.clear();
		requestLayout();
		invalidate();
	}

	public FlingTabWidget getTabWidget() {
		return tabWidget;
	}

	public int getCurrentTab() {
		return tabContent.getSelectedItemPosition();
	}

	public String getCurrentTabTag() {
		if (tabContent.getSelectedItemPosition() >= 0
				&& tabContent.getSelectedItemPosition() < tabSpecs.size()) {
			return tabSpecs.get(tabContent.getSelectedItemPosition()).getTag();
		}
		return null;
	}

	public View getCurrentTabView() {
		if (tabContent.getSelectedItemPosition() >= 0
				&& tabContent.getSelectedItemPosition() < tabSpecs.size()) {
			return tabWidget.getChildTabViewAt(tabContent
					.getSelectedItemPosition());
		}
		return null;
	}

	public View getCurrentView() {
		return tabContent.getSelectedView();
	}

	public void setCurrentTabByTag(String tag, boolean clicked) {
		int i;
		for (i = 0; i < tabSpecs.size(); i++) {
			if (tabSpecs.get(i).getTag().equals(tag)) {
				setCurrentTab(i, clicked);
				break;
			}
		}
	}

	public ViewFlow getTabContentView() {
		return tabContent;
	}

	@Override
	public boolean dispatchKeyEvent(KeyEvent event) {
		final boolean handled = super.dispatchKeyEvent(event);
		if (!handled
				&& (event.getAction() == KeyEvent.ACTION_DOWN)
				&& (event.getKeyCode() == KeyEvent.KEYCODE_DPAD_UP)
				&& (tabContent.getSelectedView().hasFocus())
				&& (tabContent.getSelectedView().findFocus()
						.focusSearch(View.FOCUS_UP) == null)) {
			tabWidget.getChildTabViewAt(tabContent.getSelectedItemPosition())
					.requestFocus();
			playSoundEffect(SoundEffectConstants.NAVIGATION_UP);
			return true;
		}
		return handled;
	}

	@Override
	public void dispatchWindowFocusChanged(boolean hasFocus) {
		tabContent.getSelectedView().dispatchWindowFocusChanged(hasFocus);
	}

	public void setCurrentTab(int index, boolean clicked) {
		if (index < 0 || index >= tabSpecs.size()) {
			return;
		}
		tabWidget.focusCurrentTab(index);
		invokeOnTabChangeListener(clicked);
		tabContent.snapToScreen(index);
	}

	public void setOnTabChangedListener(OnTabChangeListener l) {
		onTabChangeListener = l;
	}

	private void invokeOnTabChangeListener(boolean clicked) {
		if (onTabChangeListener != null) {
			onTabChangeListener.onTabChanged(getCurrentTabTag(), clicked);
		}
	}

	public interface OnTabChangeListener {
		void onTabChanged(String tabId, boolean clicked);
	}

	public class TabSpec {

		private String tag;

		private IndicatorStrategy indicatorStrategy;
		private ContentStrategy contentStrategy;

		private TabSpec(String tag) {
			this.tag = tag;
		}

		public TabSpec setIndicator(View view) {
			indicatorStrategy = new ViewIndicatorStrategy(view);
			return this;
		}

		public TabSpec setContent(Intent intent) {
			contentStrategy = new IntentContentStrategy(tag, intent);
			return this;
		}

		public String getTag() {
			return tag;
		}
	}

	private static interface IndicatorStrategy {

		View createIndicatorView();
	}

	private static interface ContentStrategy {

		View getContentView();
	}

	private static class ViewIndicatorStrategy implements IndicatorStrategy {

		private final View view;

		private ViewIndicatorStrategy(View view) {
			this.view = view;
		}

		public View createIndicatorView() {
			return view;
		}
	}

	private class IntentContentStrategy implements ContentStrategy {

		private final String tag;
		private final Intent intent;

		private View launchedView;

		private IntentContentStrategy(String tag, Intent intent) {
			this.tag = tag;
			this.intent = intent;
		}

		public View getContentView() {
			if (localActivityManager == null) {
				throw new IllegalStateException(
						"Did you forget to call 'public void setup(LocalActivityManager activityGroup)'?");
			}
			final Window w = localActivityManager.startActivity(tag, intent);
			final View wd = w != null ? w.getDecorView() : null;
			/*
			 * if (launchedView != wd && launchedView != null) { if
			 * (launchedView.getParent() != null) {
			 * tabContent.removeView(launchedView); } }
			 */
			launchedView = wd;

			if (launchedView != null) {
				launchedView.setVisibility(View.VISIBLE);
				launchedView.setFocusableInTouchMode(true);
				((ViewGroup) launchedView)
						.setDescendantFocusability(FOCUS_AFTER_DESCENDANTS);
			}
			Log.d("TAG", launchedView.toString());
			return launchedView;
		}

		@SuppressWarnings("unused")
		public View getEmptyView() {
			if (localActivityManager == null) {
				throw new IllegalStateException(
						"Did you forget to call 'public void setup(LocalActivityManager activityGroup)'?");
			}
			Intent emptyIntent = (Intent) intent.clone();

			final Window w = localActivityManager.startActivity(tag,
					emptyIntent);
			final View wd = w != null ? w.getDecorView() : null;
			if (launchedView != wd && launchedView != null) {
				if (launchedView.getParent() != null) {
					tabContent.removeView(launchedView);
				}
			}
			launchedView = wd;

			if (launchedView != null) {
				launchedView.setVisibility(View.VISIBLE);
				launchedView.setFocusableInTouchMode(true);
				((ViewGroup) launchedView)
						.setDescendantFocusability(FOCUS_AFTER_DESCENDANTS);
			}
			Log.d("TAG", launchedView.toString());
			return launchedView;
		}
	}

	class TabAdapter extends BaseAdapter {
		@Override
		public int getCount() {
			return tabSpecs.size();
		}

		@Override
		public TabSpec getItem(int position) {
			if (tabSpecs != null && tabSpecs.size() > 0)
				return tabSpecs.get(position);
			return null;
		}

		@Override
		public long getItemId(int position) {
			return position;
		}

		public String getItemTag(int position) {
			if (tabSpecs != null && tabSpecs.size() > 0)
				return tabSpecs.get(position).getTag();
			return null;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			// ����ʹ��convertView�����޷�ʵ��dispatchEvent
			TabSpec tabSpec = getItem(position);
			return tabSpec.contentStrategy.getContentView();
		}

	}

	@Override
	public void onSwitched(View view, int position) {
		tabWidget.focusCurrentTab(position);
		// to resume Activity
		tabSpecs.get(position).contentStrategy.getContentView();
		invokeOnTabChangeListener(false);
	}

	public void onScrollTabConfigurationChanged(Configuration newConfig) {
		tabContent.onConfigurationChanged(newConfig);
	}

}